﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Windows.Media.Media3D10
{
    /// <summary>
    /// Classe de base abstraite qui représente un objet lumière comportant une position dans l'espace et projetant sa lumière dans toutes les directions. 
    /// </summary>
    public abstract class PointLightBase : Light
    {
        #region Dependency Properties
        /// <summary>
        /// Identifie la propriété de dépendance <see cref="ConstantAttenuation"/>.
        /// </summary>
        public static readonly DependencyProperty ConstantAttenuationProperty =
            DependencyProperty.Register("ConstantAttenuation", typeof(double), typeof(PointLightBase));

        /// <summary>
        /// Identifie la propriété de dépendance <see cref="LinearAttenuation"/>.
        /// </summary>
        public static readonly DependencyProperty LinearAttenuationProperty =
            DependencyProperty.Register("LinearAttenuation", typeof(double), typeof(PointLightBase));

        /// <summary>
        /// Identifie la propriété de dépendance <see cref="Position"/>.
        /// </summary>
        public static readonly DependencyProperty PositionProperty =
            DependencyProperty.Register("Position", typeof(SlimDX.Vector3), typeof(PointLightBase));

        /// <summary>
        /// Identifie la propriété de dépendance <see cref="QuadraticAttenuation"/>.
        /// </summary>
        public static readonly DependencyProperty QuadraticAttenuationProperty =
            DependencyProperty.Register("QuadraticAttenuation", typeof(double), typeof(PointLightBase));

        /// <summary>
        /// Identifie la propriété de dépendance <see cref="RangeProperty"/>.
        /// </summary>
        public static readonly DependencyProperty RangeProperty =
            DependencyProperty.Register("Range", typeof(double), typeof(PointLightBase));
        #endregion

        #region Public Properties
        /// <summary>
        /// Obtient ou définit une valeur de constante par laquelle l'intensité de la lumière diminue sur la distance. 
        /// </summary>
        public double ConstantAttenuation
        {
            get { return (double)GetValue(ConstantAttenuationProperty); }
            set { SetValue(ConstantAttenuationProperty, value); }
        }

        /// <summary>
        /// Obtient ou définit une valeur qui spécifie la diminution linéaire de l'intensité de la lumière sur la distance. 
        /// </summary>
        public double LinearAttenuation
        {
            get { return (double)GetValue(LinearAttenuationProperty); }
            set { SetValue(LinearAttenuationProperty, value); }
        }

        /// <summary>
        /// Obtient ou définit un <see cref="SlimDX.Vector3"/> qui spécifie la position de la lumière dans l'espace universel. 
        /// </summary>
        [System.ComponentModel.TypeConverter(typeof(Vector3TypeConverter))]
        public SlimDX.Vector3 Position
        {
            get { return (SlimDX.Vector3)GetValue(PositionProperty); }
            set { SetValue(PositionProperty, value); }
        }

        /// <summary>
        /// Obtient ou définit une valeur qui spécifie la diminution de l'effet de la lumière sur la distance, calculée par une opération quadratique. 
        /// </summary>
        public double QuadraticAttenuation
        {
            get { return (double)GetValue(QuadraticAttenuationProperty); }
            set { SetValue(QuadraticAttenuationProperty, value); }
        }

        /// <summary>
        /// Obtient ou définit la distance au-delà de laquelle la lumière n'a aucun effet. 
        /// </summary>
        public double Range
        {
            get { return (double)GetValue(RangeProperty); }
            set { SetValue(RangeProperty, value); }
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Crée un clone modifiable de ce <see cref="PointLightBase"/>, en créant des copies complètes des valeurs de cet objet.
        /// Lors de la copie de propriétés de dépendance, cette méthode copie les références de ressources et les liaisons de données (même si elles ne peuvent plus être résolues), mais pas les animations ni leurs valeurs actuelles.
        /// </summary>
        /// <returns>
        /// Clone modifiable de l'objet actuel.
        /// La valeur de la propriété <see cref="Freezable.IsFrozen"/> de l'objet cloné est false, même si la valeur de la propriété <see cref="Freezable.IsFrozen"/> de la source est true.
        /// </returns>
        public new PointLightBase Clone()
        { 
            return base.Clone() as PointLightBase;
        }

        /// <summary>
        /// Crée un clone modifiable de ce <see cref="PointLightBase"/>, en créant des copies complètes des valeurs actuelles de cet objet.
        /// Contrairement à leurs valeurs actuelles, les références de ressources, les liaisons de données et les animations ne sont pas copiées.
        /// </summary>
        /// <returns>
        /// Clone modifiable de l'objet actuel.
        /// La valeur de la propriété <see cref="Freezable.IsFrozen"/> de l'objet cloné est false, même si la valeur de la propriété <see cref="Freezable.IsFrozen"/> de la source est true.
        /// </returns>
        public new PointLightBase CloneCurrentValue()
        {
            return base.CloneCurrentValue() as PointLightBase;
        }
        #endregion
    }
}
